package tcp

import (
	"dub/app/gate/tcp/cmdefine"
	"dub/app/gate/tcp/module"
	"dub/common"
	"dub/config"
	"dub/define"
	"dub/frame"
	"dub/secrec"
	"dub/utils"
	"fmt"
	"github.com/astaxie/beego"
	"os"
)

type TcpServer struct {
	logCfg  define.LogConfig
	tcpCfg  define.GateTcpServerConfig
	log     *utils.Logger
	ln      *frame.ListenerTcp
	modules map[uint16]common.IMoudle
}

func (t *TcpServer) Init(cfgPath string) {
	var err error
	t.tcpCfg, t.logCfg, err = config.GetGateTcpServerConfig(cfgPath)
	if err != nil {
		fmt.Println(err)
		os.Exit(2)
	}

	log := utils.NewLogger()
	log.SetConfig(t.logCfg)
	t.log = log

	t.ln = frame.NewListener(t.tcpCfg.Addr)
	t.ln.CallBack = t.lCallBack
	t.ln.OnShutdown = t.lnConnShutDown

	//用户中心的rpc信息
	tmp_rpc := utils.NewRpcProxy("tcp", t.tcpCfg.UseCenterAddr)
	err = tmp_rpc.Start()
	if err != nil {
		t.log.Errorf("server.go Init method tmp_rpc.Start method err %v\n", err)
		os.Exit(2)
	}
	secrec.AddSecRpc(secrec.ConstServiceUseRpc, tmp_rpc)

	//http服务器
	go t.httpServer()

	//添加自己的模块
	t.modules = make(map[uint16]common.IMoudle)
	t.modules[cmdefine.CmdMain_Use] = module.NewUseModule(tmp_rpc)
	t.modules[cmdefine.CmdMain_Advert] = module.NewAdvertModule(tmp_rpc)

	err = t.ln.Start()
	if err != nil {
		log.Errorf("service.go Init method frame.NewListener(r.tcpCfg.Addr) err. %v\n", err)
		os.Exit(2)
	}
	log.Infoln("tcp_server start")
}

func (t *TcpServer) httpServer() {
	//设定基础的配置
	beego.BConfig.WebConfig.ViewsPath = t.tcpCfg.WebWiew
	beego.SetStaticPath(t.tcpCfg.WebStaticUrl, t.tcpCfg.WebStaticPath)
	beego.BConfig.WebConfig.Session.SessionOn = true
	//如果想让session共享把所有的SessionProvider与SessionProviderConfig配置为一个地方，前提是在同一台服务器上
	//内存方式实现不了共享
	beego.BConfig.WebConfig.Session.SessionProvider = t.tcpCfg.SessionProvider
	beego.BConfig.WebConfig.Session.SessionProviderConfig = t.tcpCfg.SessionProviderConfig
	if t.tcpCfg.SessionProvider != "memory" {
		RegSessionGobStruct()
	}

	beego.BConfig.RunMode = t.tcpCfg.RunMode

	//日志设定
	beego.SetLogger("file", fmt.Sprintf(`{"filename":"./log/%s.log"}`, t.logCfg.DeviceName))
	//路由设定
	RouteAdd()
	//模板函数设置
	AddFunMap()
	//启动
	beego.Run(t.tcpCfg.HttpAddr)
}

//当监听关闭连接时的事件
func (t *TcpServer) lnConnShutDown(ses common.ISession) bool {
	return t.lCallBack(define.CmdRegServer_Register, define.CmdSubRegServer_Register_Shut, nil, ses)
}

//服务回调函数
func (t *TcpServer) lCallBack(mainId uint16, subId uint16, data []byte, ses common.ISession) bool {
	if mdl, ok := t.modules[mainId]; ok {
		return mdl.OnMessage(subId, data, ses)
	}
	return true
}

var tcpServer *TcpServer

func NewTcpServer() *TcpServer {
	if tcpServer == nil {
		tcpServer = new(TcpServer)
	}
	return tcpServer
}
